<template>
    <div>
        <h4>插件的开发和集成</h4>
        <ol>
            <li>基于 vue 单文件组件构建插件结构，并通过 createVnode 构建虚拟DOM</li>
            <li>基于 vue 的 render 将 createVnode 创建虚拟DOM渲染成可用的真实DOM元素</li>
            <li>按照插件本身的逻辑功能，定义功能代码并对外公开相关功能</li>
            <ul>
                <li>独立导入使用：把插件对应的文件以模块方式进行加载，并在业务中进行调用</li>
                <li>组件的全局功能使用：把插件以vue的全局功能配置方式进行定义，并在main.js完成全局加载，组件通过this进行调用</li>
            </ul>
        </ol>
        <h4>axios模块实现vue的异步数据对接</h4>
        <ol>
            <li>axios模块的集成：npm install axios --save</li>
            <li>axios加载和使用：按照环境的模块规则进行导入，并基于导入的数据和环境语法进行请求执行</li>
        </ol>
        <h4>axios的工具模块封装定义和使用</h4>
        <ol>
            <li>axios的工具模块定义：将基于axios的异步请求功能方法，按照环境下的模块规则进行独立文件定义</li>
            <li>axios加载和使用：按照环境的模块规则进行导入，并基于导入的数据和环境语法进行请求执行</li>
            <li>axios封装的工具模块的加载和使用：按照环境的模块规则进行导入，并基于导入的数据和环境语法进行请求执行</li>
        </ol>
        <h4>vue模块化开发跨域的代理服务器构建</h4>
        <ol>
            <li>vue模块化项目在构建之初都必然会集成http-proxy代理服务器模块</li>
            <li>默人情况下vue模块化项目不会启动代理服务器模块，如果需要使用通过对vue.config.js的环境配置进行启动加载</li>
            <li>通过设置 devServer.proxy 选项完成代理服务器的启动和拦截操作</li>
            <li>拦截操作：详细设置当前项目中那些请求需要被代理服务器代理发送，用于解决开发跨域问题</li>
            <li><pre>
                proxy:{
                    // key:value  => key 用于描述当前项目中需要被代理的请求前缀
                    //            => value 取值 {} 配置，用于详细描述代理的相关设置
                    "/proxyApi":{
                        // 真实服务器接口  http://127.0.0.1:30002/aaaa
                        // 例如 axios.get("/proxyApi/aaaa")  =>  http://127.0.0.1:30002/proxyApi/aaaa
                        target:"http://127.0.0.1:3002/api/", // 代理后的目标服务器
                        pathRewrite: {
                        // key 匹配的重写 正则 规则
                        // 真实服务器接口  http://127.0.0.1:30002/aaaa
                        // 例如 axios.get("/proxyApi/aaaa")  => /aaaa => http://127.0.0.1:30002/aaaa
                        "^/proxyApi": ""
                        },
                        // 改变日志等级 默认info
                        logLevel:"debug",
                        // 改变日志输出方式
                        logProvider:function(){
                        return console
                        }
                    }
                }
            </pre></li>
            <li>代理服务器的模式转换：
                <ul>
                    <li>开发代理服务器在 npm run serve 时会完成启动，但npm run build 时不会加载，因此需要有效判断不同环境的请求地址</li>
                    <li>vue模块化项目中，任何js文件都会被提供一个全局环境变量 process.env ,该变量会因为环境变化取值发生变化</li>
                    <li>其中 NODE_ENV 在 npm run serve 模式下取值 development ， 在npm run build 模式下取值 production</li>
                    <li>同时在和 vue.config.js 文件同级目录下定义 .env.模式名，也可以实现基于模式的变量自定义，但必须以 VUE_APP_变量名 进行描述</li>
                </ul>
            </li>
        </ol>
        <p v-show="showLoading">loading……</p>
        <pre>{{ result1 }}</pre>
        <input type="button" value="clear" @click="result1 = {}">
        <input type="button" value="异步请求" @click="sendAjax1()">
        <input type="button" value="异步请求-async" @click="sendAjax2()">
        <hr>
        <pre>{{ result2 }}</pre>
        <input type="button" value="第二台服务器-加载分类" @click="loadTypes()">
    </div>
</template>

<script>

// import axios from "axios";
// import api from "@/api";
import api from "@/api/dataApi";
import filmApi from "@/api/filmApi";

// import showTip from "@/plugins/notice";

export default {
    data() {
        return {
            result1:{},
            showLoading:false,
            result2:{}
        }
    },
    methods: {
        sendAjax1() {
            // console.log("axios：",axios);

            // 开启 loading
            this.showLoading = true;

            // axios.get("http://127.0.0.1:3002/api/users")
            
            // 未定义响应拦截器 
            // api.loadUserList()
            //     .then((response)=>{
            //         this.result1 = response.data;
            //     })
            //     .catch((error)=>{
            //         console.warn(error)
            //         alert("请求失败了");
            //     }).finally(()=>{
            //          // 无论promise 是成功还是失败都会执行的方法
            //          this.showLoading = false;
            //      })

            // 定义了响应拦截
            api.loadUserList()
                .then((data)=>{
                    this.result1 = data;

                    // 单独导入并进行提示插件的调用
                    // showTip("请求成功","","success");

                    // main.js 以插件形式全局安装的 $showTip 方法
                    this.$showTip("请求成功","","success")
                }).finally(()=>{
                    // 无论promise 是成功还是失败都会执行的方法
                    this.showLoading = false;
                })
        },
        async sendAjax2(){
            this.showLoading = true;

            // 未定义响应拦截器 
            // try {
            //     // let { data } = await axios.get("http://127.0.0.1:3002/api/users");
            //     let { data } = await api.loadUserList();
            //     this.result1 = data;
            // } catch (error) {
            //     console.warn(error)
            //     alert("请求失败了");
            // } finally {
            //     // 无论成功还是失败都会执行代码
            //     this.showLoading = false;
            // }

            // 定义了响应拦截
            try {
                let data = await api.loadUserList();
                this.result1 = data;
            } catch (error) {
                // throw error;
                console.error(error)
            } finally {
                // 无论成功还是失败都会执行代码
                this.showLoading = false;
            }
        },
        async loadTypes(){
            // let { data } = await axios.get("http://127.0.0.1:3000/public/types");
            let data = await filmApi.loadTypeList();
            this.result2 = data;
        }
    },
}
</script>

<style lang="scss" scoped>

</style>